<template>
	<el-card class="box-card">
		<el-form ref="queryForm" :model="query" :inline="true">
			<el-form-item label="角色名称" prop="name">
				<el-input v-model="query.name" placeholder="请输入角色名称" clearable @keyup.enter.native="handleQuery(1)" />
			</el-form-item>
			<el-form-item label="状态" prop="inuse">
				<el-select v-model="query.inuse" placeholder="全部" clearable @change="handleQuery(1)">
					<el-option label="启用" :value="1" />
					<el-option label="禁用" :value="0" />
				</el-select>
			</el-form-item>
			<el-form-item>
				<el-button type="primary" icon="el-icon-search" @click="handleQuery(1)">搜索</el-button>
				<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
			</el-form-item>
		</el-form>

		<el-row :gutter="10" class="mb20">
			<el-col :span="1.5">
				<el-button v-hasPermi="['/role/save', '/menu/listMenus']" type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
        <!-- <el-button :disabled="!ids.length" type="danger" icon="el-icon-delete" @click="handleDelete()">删除</el-button> -->
			</el-col>
		</el-row>

		<el-card class="box-card">
			<el-table v-loading="listLoading" :data="dataList" border @selection-change="handleSelectionChange">
				<!-- <el-table-column type="selection" width="50" align="center" /> -->
				<el-table-column prop="name" label="角色名称" show-overflow-tooltip width="200" />
				<el-table-column prop="about" label="描述" show-overflow-tooltip width="320" />
				<el-table-column label="状态" width="80">
					<template slot-scope="{row}">
						<el-switch v-hasPermi="['/role/update']" :value="row.inuse" :active-value="1" :inactive-value="0" @change="switchChange($event, row.id)" />
					</template>
				</el-table-column>
				<el-table-column label="创建时间" align="center" prop="ctime">
					<template slot-scope="scope">
						<span>{{ scope.row.ctime | parseTime }}</span>
					</template>
				</el-table-column>
				<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
					<template slot-scope="{row}">
						<el-button v-hasPermi="['/menu/listMenus', '/role/get/*', '/role/update']" type="text" @click="handleUpdate(row.id)">编辑</el-button>
						<el-button v-hasPermi="['/menu/getMenuIdsByRoleId/*', '/menu/addMenuRole']" type="text" @click="handleUpdate(row.id, 'menu')">分配菜单</el-button>
						<el-button v-hasPermi="['/role/permissionIds/*', '/role/updatePermissionsFromRole']" type="text" @click="$router.push(`/system/role/auth/${row.id}`)">分配权限</el-button>
						<el-button v-hasPermi="['/role/delete/*']" type="text" @click="handleDelete(row.id)">删除</el-button>
					</template>
				</el-table-column>
			</el-table>

			<pagination v-show="total>0" :total="total" :page.sync="query.pageNum" :limit.sync="query.pageSize" @pagination="handleQuery" />
		</el-card>

		<!-- 添加或修改角色 -->
		<el-dialog :title="(formModel.id?'编辑':'新增')+'角色'" :visible.sync="formVisible" width="600px" append-to-body>
			<el-form ref="formModel" :model="formModel" :rules="formRules" label-width="80px">
				<el-row>
					<el-col :span="12">
						<el-form-item label="角色名称" prop="name">
							<el-input v-model="formModel.name" placeholder="请输入角色名称" maxlength="20" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="状态">
							<el-switch v-model="formModel.inuse" :active-value="1" :inactive-value="0" />
						</el-form-item>
					</el-col>
					<el-col :span="24">
            <el-form-item label="描述">
              <el-input v-model="formModel.about" type="textarea" placeholder="请输入描述内容"></el-input>
            </el-form-item>
					</el-col>
				</el-row>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button @click="formVisible=!formVisible;reset;">取 消</el-button>
				<el-button :loading="submitLoading" type="primary" @click="submitForm">确 定</el-button>
			</div>
		</el-dialog>
		<!-- 分配菜单 -->
		<el-dialog title="分配菜单" :visible.sync="menuVisible" width="600px" append-to-body>
      <div>
        <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
        <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
        <el-tree
          class="tree-border"
          :data="menuList"
          :props="{
            label: 'name',
            children: 'children'
          }"
          ref="menu"
          node-key="id"
          show-checkbox
          empty-text="加载中，请稍后">
        </el-tree>
      </div>
			<div slot="footer" class="dialog-footer">
				<el-button @click="menuVisible=!menuVisible;resetModel('menu');">取 消</el-button>
				<el-button :loading="submitMenuLoading" type="primary" @click="submitMenuForm">确 定</el-button>
			</div>
		</el-dialog>
	</el-card>
</template>

<script>
import { roleListPage, roleGetId, roleDeleteId, roleDeleteBatch, roleSave, roleUpdate } from '@/api/system/role'
import { listMenus, getMenuIdsByRoleId, addMenuRole } from '@/api/system/menu'

export default {
  data () {
    return {
      // 列表数据
      query: {
        pageNum: 1,
        pageSize: 10
      },
      total: 0,
      dataList: null,
      listLoading: false,
      ids: [],
      // 新增/编辑权限
      formVisible: false,
      submitLoading: false,
      formModel: {
        inuse: 1
      },
      formRules: {
        name: [
          { required: true, message: "角色名称不能为空", trigger: "blur" }
        ]
      },
      // 分配菜单
      menuVisible: false,
      submitMenuLoading: false,
      menuList: [],
      menuExpand: false,
      menuNodeAll: false,
      menuOptions: [],
      menuModel: {
        menuIds: []
      }
    }
  },
  created () {
    this.handleQuery()
  },
  methods: {
    // 获取筛选信息
    getOptions () {
      listMenus().then(res => {
        this.menuList = res.data
      })
    },
    // 树权限（展开/折叠）
    handleCheckedTreeExpand(value, type) {
      if (type == 'menu') {
        let treeList = this.menuList;
        for (let i = 0; i < treeList.length; i++) {
          this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value;
        }
      }
    },
    // 树权限（全选/全不选）
    handleCheckedTreeNodeAll(value, type) {
      if (type == 'menu') {
        this.$refs.menu.setCheckedNodes(value ? this.menuList: []);
      }
    },
    // 所有菜单节点数据
    getMenuAllCheckedKeys() {
      // 目前被选中的菜单节点
      let checkedKeys = this.$refs.menu.getCheckedKeys();
      // 半选中的菜单节点
      let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys();
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
      return checkedKeys;
    },
    submitMenuForm(){
      this.submitMenuLoading = true
      this.menuModel.menuIds = this.getMenuAllCheckedKeys();
      addMenuRole(this.menuModel).then(() => {
        this.$message.success('添加成功')
        this.resetModel('menu')
        this.menuVisible = !this.menuVisible
      })
      this.submitMenuLoading = false
    },
    resetModel(type = 'menu') {
      if (type === 'menu') {
        if (this.$refs.menu != undefined) {
          this.$refs.menu.setCheckedKeys([]);
        }
        this.menuModel = { menuIds:[] }
        this.menuExpand = false
        this.menuNodeAll = false
      }
    },
    // 多选框选中数据
    handleSelectionChange (selection) {
      this.ids = selection.map(item => item.id)
    },
    handleQuery (pageNum) {
      if (pageNum===1) this.query.pageNum = 1
      this.listLoading = true
      roleListPage(this.query).then(res => {
        const { records, total } = res.data
        this.dataList = records
        this.total = total
        this.listLoading = false
      }).catch(err => {
        if (err.code === -103) {
          this.$router.push('/403')
        }
        this.listLoading = false
      })
    },
    resetQuery () {
      this.resetForm('queryForm')
      this.handleQuery(1)
    },
    handleAdd () {
      this.getOptions()
      this.reset()
      this.formVisible = !this.formVisible
    },
    handleUpdate (roleId, type = 'edit') {
      if (type === 'menu') {
        this.getOptions()
        getMenuIdsByRoleId(roleId).then(res => {
          const menuIds = res.data
          this.menuModel = { roleId, menuIds }
          setTimeout(() => {
            menuIds.forEach((v) => {
              this.$nextTick(()=>{
                this.$refs.menu.setChecked(v, true ,false);
              })
            })
          }, 100);
        })
        this.menuVisible = !this.menuVisible
        return
      }
      this.handleAdd()
      roleGetId(roleId).then(res => {
        this.formModel = { ...res.data }
      })
    },
    handleDelete (id) {
      if (id) {
        this.$confirm(`请确认是否要删除该角色?`, { type: 'warning' }).then(() => {
          roleDeleteId(id).then(() => {
            this.$message.success('删除成功')
            this.handleQuery()
          })
        })
      } else {
        this.$confirm(`请确认是否要删除该批角色?`, { type: 'warning' }).then(() => {
          roleDeleteBatch(this.ids).then(() => {
            this.$message.success('删除成功')
            this.handleQuery()
          })
        })
      }
    },
    // 新增/编辑
    submitForm () {
      this.submitLoading = true
      this.$refs["formModel"].validate(async valid => {
        if (valid) {
          try {
            if (this.formModel.id) {
              await roleUpdate(this.formModel)
              this.$message.success('修改成功')
            } else {
              await roleSave(this.formModel)
              this.$message.success('新增成功')
            }
            this.formVisible = !this.formVisible
            this.handleQuery()
            this.submitLoading = false
          } catch (error) {
            this.submitLoading = false
          }
        } else {
          this.submitLoading = false
        }
      })
    },
    // 表单重置
    reset () {
      this.formModel = {
        inuse: 1
      }
      this.resetForm("formModel")
    },
    // 状态变更
    switchChange (inuse, id) {
      this.$confirm(`请确认是否要${inuse === 0 ? '禁用' : '启用'}该角色?`, { type: 'warning' }).then(() => {
        roleUpdate({ id, inuse }).then(() => {
          this.handleQuery()
        })
      })
    }
  }
}
</script>
